---
title: <FieldLabel>
---

import { ConfigPreview } from "../../../../components/Preview";
import { FieldLabel } from "@/puck";
import { Globe } from "lucide-react";

# \<FieldLabel\>

Render a styled `label` when creating [`custom` fields](/docs/api-reference/fields/custom).

<ConfigPreview
  label="Example"
  componentConfig={{
    fields: {
      title: {
        type: "custom",
        render: () => {
          return (
            <FieldLabel label="Title">
              <input
                style={{ background: "white", border: "1px solid black" }}
              />
            </FieldLabel>
          );
        },
      },
    },
    defaultProps: {
      title: "Hello, world",
    },
  }}
/>

```tsx {1,4-6} copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel label="Title">
    <input />
  </FieldLabel>
);

const config = {
  components: {
    Example: {
      fields: {
        title: {
          type: "custom",
          render: MyCustomField,
        },
      },
    },
  },
};
```

## Props

| Param                     | Example                | Type             | Status   |
| ------------------------- | ---------------------- | ---------------- | -------- |
| [`label`](#label)         | `label: "Title"`       | String           | Required |
| [`children`](#children)   | `children: <div />`    | ReactNode        | -        |
| [`className`](#classname) | `className: "MyLabel"` | String           | -        |
| [`el`](#el)               | `el: false`            | "label" \| "div" | -        |
| [`icon`](#icon)           | `icon: <svg />`        | ReactNode        | -        |
| [`readOnly`](#readonly)   | `readOnly: false`      | Boolean          | -        |

## Required props

### `label`

The label string for the fields.

```tsx /label="Title"/ copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel label="Title">
    <input />
  </FieldLabel>
);

// ...
```

## Optional props

### `children`

A node to render inside the FieldLabel's internal `<label>` element. You can also define your input element as a sibling.

```tsx {5} copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel label="Title">
    <input />
  </FieldLabel>
);

// ...
```

### `className`

Define a custom class for the field label.

```tsx /className="MyClass"/ copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel className="MyClass" label="Title">
    <input />
  </FieldLabel>
);

// ...
```

### `el`

Specify whether to render a `label` or `div`. **Defaults to `"label"`**.

```tsx /el="div"/ copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel el="div" label="Title">
    <input />
  </FieldLabel>
);

// ...
```

### `icon`

Render an icon before the label text. Puck uses [lucide-react](https://lucide.dev/guide/packages/lucide-react) internally.

```tsx /icon={<Globe size="16" />}/ copy
import { FieldLabel } from "@measured/puck";
import { Globe } from "lucide-react";

const CustomField = () => (
  <FieldLabel icon={<Globe size="16" />} label="Title">
    <input />
  </FieldLabel>
);

// ...
```

<ConfigPreview
  label="Example"
  componentConfig={{
    fields: {
      title: {
        type: "custom",
        render: () => {
          return (
            <FieldLabel label="Title" icon={<Globe size="16" />}>
              <input style={{ border: "1px solid black" }} />
            </FieldLabel>
          );
        },
      },
    },
    defaultProps: {
      title: "Hello, world",
    },
  }}
/>

### `readOnly`

Indicate to the user that this field is in a read-only state by showing a padlock icon to the right of the text.

```tsx /readOnly/1 copy
import { FieldLabel } from "@measured/puck";

const CustomField = () => (
  <FieldLabel label="Title" readOnly>
    <input readOnly />
  </FieldLabel>
);

// ...
```

<ConfigPreview
  label="Example"
  componentConfig={{
    fields: {
      title: {
        type: "custom",
        render: () => {
          return (
            <div style={{ maxWidth: "max-content" }}>
              <FieldLabel label="Title" readOnly>
                <input style={{ border: "1px solid black" }} readOnly />
              </FieldLabel>
            </div>
          );
        },
      },
    },
    defaultProps: {
      title: "Hello, world",
    },
  }}
/>
